/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.thienloc.omap.controller;

import com.thienloc.omap.jdbc.dao.RequestQueueDao;
import com.thienloc.omap.jdbc.entity.RequestQueue;
import com.thienloc.omap.util.Constant;
import com.thienloc.omap.util.JsfUtil;
import java.io.File;
import java.io.FileReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

/**
 *
 * @author GiangLT
 */
@ManagedBean
@ViewScoped
public class RequestQueueBean2 extends AbstractCrudBean {

    private RequestQueueDao dao = new RequestQueueDao();
    @ManagedProperty(value = "#{applicationBean}")
    protected ApplicationBean applicationBean;
    private RequestQueue selected;
    private List<RequestQueue> list;
    private RequestQueue[] selectedList;
    private boolean searched = false;
    private final int MAX_RESULT = 250;
    private final boolean CHECK_TIME = true;
    private boolean nullServiceOnly = false;

    public void toggleView() {
        try {
            List<String> statusesToSearch = new ArrayList<String>();
            statusesToSearch.add("WAITING");

            if (nullServiceOnly) {

                list = dao.findByStatusNullServiceOnly(statusesToSearch, MAX_RESULT, true);
            } else {
                list = dao.findByStatus(statusesToSearch, MAX_RESULT, true);
            }

            for (RequestQueue requestQueue : list) {
                requestQueue.setSelectTime(new Date());
            }
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }

    }

    public RequestQueue[] getSelectedList() {
        return selectedList;
    }

    public void setSelectedList(RequestQueue[] selectedList) {
        this.selectedList = selectedList;
    }

    public List<RequestQueue> getList() {
        return list;
    }

    public void setList(List<RequestQueue> list) {
        this.list = list;
    }

    public RequestQueue getSelected() {
        return selected;
    }

    public void setSelected(RequestQueue selected) {
        this.selected = selected;
    }

    @Override
    protected void validateForm() throws Exception {
    }

    @Override
    protected Logger getLogger() {
        return LoggerFactory.getLogger(RequestQueueBean2.class);
    }

    @Override
    protected void resetToCreateFormAction() throws Exception {
        List<String> statusesToSearch = new ArrayList<String>();
        statusesToSearch.add("WAITING");

        if (nullServiceOnly) {
            list = dao.findByStatusNullServiceOnly(statusesToSearch, MAX_RESULT, true);
        } else {
            list = dao.findByStatus(statusesToSearch, MAX_RESULT, true);
        }


        for (RequestQueue requestQueue : list) {
            requestQueue.setSelectTime(new Date());
        }
        selected = new RequestQueue();
        edit = false;
        view = false;
    }

    @Override
    protected void findSelected(int id) throws Exception {
        selected = dao.find((long) id);
    }

    @Override
    protected void createSelected() throws Exception {
//        dao.create(selected);
//        resetToCreateForm();
//        JsfUtil.addSuccessMessage("Thành công!", "Đã thêm mới thành công một bản ghi");
    }

    @Override
    protected void editSelected() throws Exception {
        dao.edit(selected);
        resetToCreateForm();
        JsfUtil.addSuccessMessage("Thành công!", "Đã cập nhật thành công một bản ghi");
    }

    @Override
    protected void removeSelected() throws Exception {
        int size = selectedList.length;
        if (size == 0) {
            JsfUtil.addMessage(FacesMessage.SEVERITY_WARN, "Không có gì để xóa", "Hãy click chọn các bản ghi cần xóa");
            return;
        }
        for (RequestQueue item : selectedList) {
            dao.remove(item);
        }
        resetToCreateForm();
        JsfUtil.addSuccessMessage("Thành công!", "Đã xóa thành công " + size + " bản ghi");
    }

    @Override
    protected void prepareViewAction() throws Exception {
        view = true;
        edit = false;
        if (selectedList == null || selectedList.length == 0) {
            JsfUtil.addErrorMessage("Lỗi", "Bạn chưa tích chọn bản ghi cần hiển thị");
            return;
        }
        selected = selectedList[0];
        if (selectedList.length > 1) {
            JsfUtil.addMessage(FacesMessage.SEVERITY_WARN, "Cảnh báo hiển thị", "Bạn đã chọn nhiều hơn 1 bản ghi. Chỉ bản ghi trên cùng được hiển thị");
        }
    }

    @Override
    protected void prepareEditAction() throws Exception {
        view = false;
        edit = true;
        if (selectedList == null || selectedList.length == 0) {
            JsfUtil.addErrorMessage("Lỗi", "Bạn chưa tích chọn bản ghi cần hiển thị");
            return;
        }
        selected = selectedList[0];
        if (selectedList.length > 1) {
            JsfUtil.addMessage(FacesMessage.SEVERITY_WARN, "Cảnh báo hiển thị", "Bạn đã chọn nhiều hơn 1 bản ghi. Chỉ bản ghi trên cùng được hiển thị");
        }
    }

    public void reload() {
        if (searched) {
        } else {
            resetToCreateForm();
        }
    }

    public void batchUpdate() {
        try {
            dao.batchUpdate(Arrays.asList(selectedList));
            JsfUtil.addSuccessMessage("Thành công", "Đã cập nhật " + selectedList.length + " yêu cầu");
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }

//        for (RequestQueue requestQueue : selectedList) {
//            try {
//                dao.edit(requestQueue);
//            } catch (Exception ex) {
//                logAndNotifyError(ex);
//            }
//        }

    }

    public void setCompleted(Long id) {
        try {
            RequestQueue rq = dao.find(id);
            rq.setStatus("COMPLETED");
            dao.edit(rq);

            JsfUtil.addSuccessMessage("Thành công", "Đã chuyển yêu cầu của số " + rq.getMsisdn() + " sang trạng thái COMPLETED");
            resetToCreateForm();
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
    }

    public void updateAll() {
        try {
            if (!list.isEmpty()) {
                int cnt = 0;
                for (RequestQueue request : list) {
                    try {
                        RequestQueue rq = dao.find(request.getRequestId());
                        if (rq.getRequestDetail() == null) {
                            rq.setRequestDetail("");
                        }
                        if (rq.getOldContent() == null) {
                            rq.setOldContent("");
                        }
                        // tim lai trong DB

                        if (request.getRequestDetail() != null && !request.getRequestDetail().isEmpty()) {
//                            logger.log(Level.INFO, "{0}: Request Detail is not empty", request.getMsisdn());
                            if ((rq.getStatus() != null && rq.getStatus().equals("WAITING"))) {
//                                logger.log(Level.INFO, "{0}: Request status WAITING", request.getMsisdn());
                                if (!rq.getRequestDetail().equals(request.getRequestDetail())) {
//                                    logger.log(Level.INFO, "{0}: New Detail: \"{1}\" || Old detail: \"{2}\" ", new Object[]{request.getMsisdn(), request.getRequestDetail(), rq.getRequestDetail()});
                                    if (!rq.getOldContent().equals(request.getRequestDetail())) {
//                                        logger.log(Level.INFO, "{0}: New Detail: \"{1}\" || Old Content: \"{2}\" ", new Object[]{request.getMsisdn(), request.getRequestDetail(), rq.getOldContent()});
                                        Properties properties = new Properties();
                                        File file = new File(Constant.CONFIG_FOLDER + Constant.CONFIG_FILE_NAME);
                                        properties.load(new FileReader(file));
                                        String checkTime = properties.getProperty("requestQueue.checkTime", "false");
                                        if (Boolean.parseBoolean(checkTime)) {
                                            DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
                                            if (request.getSelectTime().after(rq.getLastCheckTime())) {
                                                logger.info("[{}]:  {}: Select time ({}) is after last check time ({})", new Object[]{getUsername(), request.getMsisdn(), dateFormat.format(request.getSelectTime()), dateFormat.format(rq.getLastCheckTime())});
                                                request.setStatus("WAITING_UPDATE");
                                                request.setLastCheckTime(new Date());
                                                dao.edit(request);//thuc hien update vao Db
//                                                logger.log(Level.INFO, "{0}: Updated neew detail: \"{1}\"", new Object[]{request.getMsisdn(), request.getRequestDetail()});
                                                cnt++;

                                            } else {
                                                logger.info("[{}]:  {}: Select time ({}) is before last check time ({})", new Object[]{getUsername(), request.getMsisdn(), dateFormat.format(request.getSelectTime()), dateFormat.format(rq.getLastCheckTime())});
                                            }
                                        } else {
                                            request.setStatus("WAITING_UPDATE");
                                            request.setLastCheckTime(new Date());
                                            dao.edit(request);//thuc hien update vao Db
//                                            logger.log(Level.INFO, "{0}: Updated neew detail: \"{1}\"", new Object[]{request.getMsisdn(), request.getRequestDetail()});
                                            cnt++;
                                        }
//                                        logger.log(Level.INFO, "{0}: ==============================================", request.getMsisdn());
                                    }
                                }
                            }
                        }


                    } catch (Exception ex) {
                        logAndNotifyError(ex);
                    }
                }
                if (cnt > 0) {
                    JsfUtil.addSuccessMessage("Thành công", "Đã cập nhật " + cnt + " yêu cầu");
                }
            }

            resetToCreateForm();
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
    }

    public void changeItem(Long requestId) {
        try {
            if (selected.getRequestId() != null) {
                editSelected();
            }
            selected = dao.find(requestId);
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
    }

    public void updateItem(RequestQueue request) {
        try {
            RequestQueue rq = dao.find(request.getRequestId());
            if (rq.getRequestDetail() == null) {
                logger.info("[{}]:  Request detail of {} is null", getUsername(), rq.getMsisdn());
                rq.setRequestDetail("");
            }
            if (rq.getOldContent() == null) {
                logger.info("[{}]:  Old content of {} is null", getUsername(), rq.getMsisdn());
                rq.setOldContent("");
            }
            // tim lai trong DB

            if (request.getRequestDetail() != null && !request.getRequestDetail().isEmpty()) {
                if ((rq.getStatus() != null && rq.getStatus().equals("WAITING"))
                        && (!rq.getRequestDetail().equals(request.getRequestDetail()))
                        && (!rq.getOldContent().equals(request.getRequestDetail()))) {

                    Properties properties = new Properties();
                    File file = new File(Constant.CONFIG_FOLDER + Constant.CONFIG_FILE_NAME);
                    properties.load(new FileReader(file));
                    String checkTime = properties.getProperty("requestQueue.checkTime", "true");
                    if (Boolean.parseBoolean(checkTime)) {
                        DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
                        if (request.getSelectTime().after(rq.getLastCheckTime())) {
                            logger.info("[{}]:  {0}: Select time ({}) is after last check time ({})", new Object[]{getUsername(), request.getMsisdn(), dateFormat.format(request.getSelectTime()), dateFormat.format(rq.getLastCheckTime())});
                            request.setStatus("WAITING_UPDATE");
                            request.setLastCheckTime(new Date());
                            dao.edit(request);//thuc hien update vao Db
                            JsfUtil.addSuccessMessage("Thành công", "Đã cập nhật yêu cầu của số " + request.getMsisdn());

                        } else {
                            logger.info("[{}]:  {0}: Select time ({}) is before last check time ({})", new Object[]{getUsername(), request.getMsisdn(), dateFormat.format(request.getSelectTime()), dateFormat.format(rq.getLastCheckTime())});
                        }
                    } else {
                        request.setStatus("WAITING_UPDATE");
                        request.setLastCheckTime(new Date());
                        dao.edit(request);//thuc hien update vao Db
                        JsfUtil.addSuccessMessage("Thành công", "Đã cập nhật yêu cầu của số " + request.getMsisdn());
                    }
                }
            }
        } catch (Exception ex) {
            logAndNotifyError(ex);
        }
    }

    public ApplicationBean getApplicationBean() {
        return applicationBean;
    }

    public void setApplicationBean(ApplicationBean applicationBean) {
        this.applicationBean = applicationBean;
    }

    public boolean isNullServiceOnly() {
        return nullServiceOnly;
    }

    public void setNullServiceOnly(boolean nullServiceOnly) {
        this.nullServiceOnly = nullServiceOnly;
    }
}
